/**
 * 该场景固定长宽: 1920 x 1080
 * HTML 设置方案
 * #main
 *   #background (底层, 1920x1080)
 *   #content (底层, 1920x1080)
 */

function createScene(context) {
	return new context.Scene({

		zrender : null,
		zr : null,
		require : ['zrender'],
		width : 1920,
		height : 1080,
		arg : null,

		/*
		 * 左上角的精灵
		 */
		spritesParam : {
			// 很多白色方块部分 wb (white block)
			wbOffsetX : 15,
			wbOffsetY : 180,
			wbStepX : 20, // 方块位置间隔
			wbStepY : 20,
			wbWidth : 15, // 方块长宽
			wbHeight : 15,
			wbSprites : null, // 两元数组, 放 Rect 的, [x][y]
			wbShows : null,
			wbUpdateHandle : 0, // 更新事件的句柄
	
			// 白条上方的块 tl (tile)
			tlSprite1 : null, // 最右边的不规则块
			tlSprite2 : null,
			tlSprite3 : null,
			tlSprite4 : null,
	
			// 文本 tx
			txSprites : [],
	
			// 整个大框
			screenStroke : null,
	
			// 右下角
			timerCorner : null,
	
			empty : null
		},

    init(libs) {
			this.zrender = libs.zrender;

			var main = document.getElementById('main');
			main.style.width = this.width + 'px';
			main.style.height = this.height + 'px';
			
			this.zr = this.zrender.init(main);

			// 创建常量表
			this.createStaticTable();

			// **** 绘画部分

			// 底
			this.createBackground();
			// 斑点
			this.createStain();
			// 左上角的精灵
			this.createSprites();
			// 主屏幕
			this.createScreen();
			// 底
			this.createBottom();
		},
		
		/*
		 * 收集状态数据
		 */
		collectInfo() {
			return this.arg;
		},

		/*
		 * 创建常量表
		 */
		createStaticTable() {
			let sinTable = new Array(40);
			for (var i = 0; i < sinTable.length; i++) {
				sinTable[i] = Math.sin(Math.PI / 20 * i);
			}

			this.staticTable = {
				sin : sinTable
			};
		},
		
		/* **********
		 *   展示   *
		 ********** */

		createBackground() {
			// 背景版
			this.zr.add(new this.zrender.Rect({
				shape: {
					width: this.width,
					height: this.height
				},
				style: {
					fill: new this.zrender.LinearGradient(
						0, 0, 0, 1,
						[
							{offset:0, color:'#114c6b'},
							{offset:0.2, color:'#15597c'},
							{offset:0.76, color:'#15597c'},
							{offset:1, color:'#0d3a51'}
						]
					),
					opacity: 1
				},
				position: [0, 0],
				z: 0
			}));

			// 扫描线
			let lineList = [];
			for (var i = 0; i < this.height / 3; i ++) {
				var line = new this.zrender.Line({
					shape: {
						x1: 0,
						y1: i * 3,
						x2: this.width,
						y2: i * 3
					}
				});
				lineList.push(line);
			}
			this.zr.add(this.zrender.path.mergePath(lineList, {
				style: {
					stroke: 'black',
					fill: 'none',
					opacity: 0.4,
					lineWidth: 1
				},
				position: [0, 0],
				z: 0
			}));

			// 白条
			this.zr.add(new this.zrender.Rect({
				shape: {
					width: 1920,
					height: 88
				},
				style: {
					fill: new this.zrender.LinearGradient(
						0, 0, 0, 1,
						[
							{offset:0, color:'#a8daed00'},
							{offset:0.1, color:'#a8daedff'},
							{offset:0.9, color:'#d1e5f4ff'},
							{offset:1, color:'#d1e5f400'}
						]
					),
					opacity: 1
				},
				position: [0, 90],
				z: 10
			}));
		},

		uniform2NormalDistribution () {
			let sum=0.0;
			for(let i=0; i<12; i++){
				sum=sum+Math.random();
			}
			return sum-6.0;
		},
		
		createStain () {
			let colors = [
				['#ef6a','#ed4a','#e937','#b730'],
				['#ea1a','#b40a','#a307','#a200'],
				['#fffa','#edca','#ecb7','#eca0']
			]
		
			this.stainParam = {
				colors : colors,
				blocks : [],
				stains : []
			}
		
			this.stainParam.blocks.push(new this.zrender.Circle({
				shape: {
					r: 100
				},
				style: {
					fill: new this.zrender.RadialGradient(
							0.5, 0.5, 0.5,
							[
								{offset:0, color:colors[2][0]},
								{offset:0.5, color:colors[2][1]},
								{offset:1, color:colors[2][3]}
							]
						),
						opacity: 0.3,
						blend: 'lighter'
					},
					scale: [5, 1],
					position: [200, 800],
					z: 1
				}));
		
			// 色块
			this.zr.add(this.stainParam.blocks[0]);
		
			// 亮点
			for (let i = 0; i < 100; i++) {
				let x = Math.random() * 2000 - 40;
				let y = this.uniform2NormalDistribution() * 50 + 800;
				let circle = this.buildCircle(x, y);
		
				this.stainParam.stains.push({
					circle : circle,
					x : x,
					y : y,
					speed : 1 + Math.random() * 10
				});
				this.zr.add(circle);
			}
		
			let thiz = this;
			setInterval(function() {
				thiz.updateStain();
			}, 1000);
		},
		
		buildCircle (x, y) {
			let r = Math.random() > 0.5 ? Math.random() * 30 + 5 : Math.random() * 8 + 5;
			let opacity = Math.random() * 0.5 + 0.2;
			let colors = this.stainParam.colors;
			let colorIdx = parseInt(Math.random() * colors.length);
		
			return new this.zrender.Circle({
				shape: {
					r: r
				},
				style: {
					fill: new this.zrender.RadialGradient(
						0.5, 0.5, 0.5,
						[
							{offset:0, color:colors[colorIdx][0]},
							{offset:0.8, color:colors[colorIdx][1]},
							{offset:0.92, color:colors[colorIdx][2]},
							{offset:1, color:colors[colorIdx][3]}
						]
					),
					opacity: opacity,
					blend: 'lighter'
				},
				position: [x, y],
				z: 1
			});
		},
		
		updateStain () {
			if( document.hidden ) {return;}
			this.stainParam.blocks[0].animateTo({
				opacity: 0.3 + 0.1 * Math.random(),
				scale: [4 + 2 * Math.random(), 0.8 + 0.4 * Math.random()]
			}, 900, 0, 'quadraticInOut');
		
			for (let i = 0; i < this.stainParam.stains.length; i++) {
				let circleObject = this.stainParam.stains[i];
				let x0 = circleObject.x - circleObject.speed;
		
				if (x0 < -50) {
					// 删除
					this.zr.remove(circleObject.circle);
					this.stainParam.stains.splice(i--, 1);
		
					// 产生新的
					let y = this.uniform2NormalDistribution() * 50 + 800;
					let circle = this.buildCircle(1970, y);
		
					this.stainParam.stains.push({
						circle : circle,
						x : 1970,
						y : y,
						speed : 1 + Math.random() * 10
					});
					this.zr.add(circle);
		
				} else {
					circleObject.circle.animateTo({
						position : [x0, circleObject.y]
					}, 1000, 0);
					circleObject.x = x0;
				}
			}
		},

		createSprites () {
			let thiz = this;

			// 很多白色方块 wb
			// 左上角方块 (15, 175), 右下角方块 (575, 315), 每个方块 15x15, 每两格间隙 5, 共 29 列, 8 行
			this.spritesParam.wbSprites = [];
			this.spritesParam.wbShows = [];

			for (let x = 0; x < 29; x++) {
				this.spritesParam.wbSprites[x] = [];
				this.spritesParam.wbShows[x] = [];
				for (let y = 0; y < 8; y++) {
					this.spritesParam.wbShows[x][y] = false;
					this.spritesParam.wbSprites[x][y] = new this.zrender.Rect({
						shape: {
							width: this.spritesParam.wbWidth,
							height: this.spritesParam.wbHeight,
						},
						style: {
							fill: '#77b3d5',
							opacity: 0
						},
						position: [
							this.spritesParam.wbOffsetX + x * this.spritesParam.wbStepX,
							this.spritesParam.wbOffsetY + y * this.spritesParam.wbStepY
						],
						z: 5
					});
					this.zr.add(this.spritesParam.wbSprites[x][y]);
				}
			}
			this.spritesParam.wbUpdateHandle = setInterval(function() {
				thiz.updateWbs();
			}, 5000);

			// 白条上方的块 tl
			this.spritesParam.tlSprite1 = new this.zrender.Polyline({
				shape: {
					points: [
						[587, 63], // 右上
						[581, 85], // 右下
						[402, 85], // 左下
						[405, 73], // 左上
						[526, 73],
						[529, 63]
					]
				},
				style: {
					fill: '#77b3d5',
					opacity: 0.4,
					stroke: 'none'
				},
				z: 5
			});
			this.zr.add(this.spritesParam.tlSprite1);
			this.spritesParam.tlSprite2 = new this.zrender.Polyline({
				shape: {
					points: [
						[398, 73], // 右上
						[395, 85], // 右下
						[376, 85], // 左下
						[379, 73]  // 左上
					]
				},
				style: {
					fill: '#77b3d5',
					opacity: 0.4,
					stroke: 'none'
				},
				z: 5
			});
			this.zr.add(this.spritesParam.tlSprite2);
			this.spritesParam.tlSprite3 = new this.zrender.Polyline({
				shape: {
					points: [
						[372, 73], // 右上
						[369, 85], // 右下
						[350, 85], // 左下
						[353, 73]  // 左上
					]
				},
				style: {
					fill: '#77b3d5',
					opacity: 0.4,
					stroke: 'none'
				},
				z: 5
			});
			this.zr.add(this.spritesParam.tlSprite3);
			this.spritesParam.tlSprite4 = new this.zrender.Polyline({
				shape: {
					points: [
						[346, 73], // 右上
						[343, 85], // 右下
						[324, 85], // 左下
						[327, 73]  // 左上
					]
				},
				style: {
					fill: '#77b3d5',
					opacity: 0.4,
					stroke: 'none'
				},
				z: 5
			});
			this.zr.add(this.spritesParam.tlSprite4);

			// 文字
			// let text = 'FLASH IN THE DARK';
			let pos = [ // x, width
				[0, 11],
				[11, 10],
				[21, 12],
				[33, 13],
				[46, 13],

				[66, 7],
				[73, 13],

				[95, 10],
				[105, 13],
				[118, 11],

				[137, 13],
				[150, 12],
				[162, 13],
				[175, 13]
			]

			for (let i = 0; i < pos.length; i++) {
				let x = pos[i][0];
				let width = pos[i][1];

				let txSprite = new this.zrender.Image({
					style: {
						image: context.assetPath('show/texts.png'),
						opacity: 0.6
					},
					position: [130, 73],
					z: 5
				});
				var clipPath = new this.zrender.Rect({
					shape: {
						x: x,
						y: 0,
						width: width,
						height: 12
					}
				});
				txSprite.setClipPath(clipPath);

				this.zr.add(txSprite);
				this.spritesParam.txSprites.push(txSprite);
			}
			this.spritesParam.wbUpdateHandle = setInterval(function() {
				thiz.updateTlAndTxs();
			}, 10000);

			this.zr.add(new this.zrender.Image({
				style: {
					image: context.assetPath('show/mural.png'),
					opacity: 0.4,
					shadowBlur: 10,
					shadowColor: '#FFF'
				},
				scale: [0.63, 0.63],
				position: [0, 526],
				z: 5
			}));
		},

		updateWbs () {
			if( document.hidden ) {return;}

			let wbSprites = this.spritesParam.wbSprites;
			let wbShows = this.spritesParam.wbShows;

			for (let x = 0; x < wbSprites.length; x++) {
				let array = wbSprites[x];
				for (let y = array.length - 1; y >= 0; y--) {
					let wb = array[y];

					let show;
					if (y == array.length - 1) {
						show = Math.random() <= 0.05;
					} else {
						if (wbShows[x][y + 1]) {
							show = Math.random() <= 0.98 - 0.04 * y;
						} else {
							show = Math.random() <= 0.64 - y * 0.08;
						}
					}

					// 它是否显示呢？
					wbShows[x][y] = show;
					if (show) {
						// wb.stopAnimation(false);
						wb.animate('style', false)
						.delay(x * 100 + y * 50)
						.when(700, {
							opacity: 0.6
						}).when(1800, {
							opacity: 0.4
						}).when(6000 + parseInt(Math.random() * 3000), {
							opacity: 0
						}).start('quadraticOut');
					}
				}
			}
		},

		updateTlAndTxs () {
			if( document.hidden ) {return;}

			let spritesParam = this.spritesParam;
			let tls = spritesParam.txSprites.concat([
					spritesParam.tlSprite4,
					spritesParam.tlSprite3,
					spritesParam.tlSprite2,
					spritesParam.tlSprite1
				]);
			
			for (let i = tls.length - 1; i >= 0; i--) {
				let el = tls[i];
				el.animate('style', false)
					.delay(800 * (tls.length - i))
					.when(150, {
						opacity: 0.1
					}).when(300, {
						opacity: 0.4
					}).when(450, {
						opacity: 0.1
					}).when(600, {
						opacity: 0.6
					}).start('quadraticOut');
			}

		},
		
		/*
			* 屏幕部分
			*/
		
		createScreen () {
			// 去掉窗口这部分的
			this.zr.add(new this.zrender.Rect({
				shape: {
					width: 1298,
					height: 978
				},
				style: {
					fill: '#FFF',
					opacity: 1,
					blend: 'destination-out'
				},
				position: [600, 12],
				z: 15
			}));

			// 框框右下角这个小框的底
			/*this.zr.add(this.spritesParam.screenBg = new zrender.Polyline
			({
				shape: {
					points: [
						[1900, 990], // 右下框右上角 D
						[1900, 1072],// 右下框右下角 E3
						[1528, 1072],// 右下框左下角 E2
						[1503, 988]  // 右下框左上角 E1
					]
				},
				style: {
					fill: new zrender.LinearGradient(
						0, 0, 0, 1,
						[
							{offset:0.4, color:'#439fce60'},
							{offset:0.7, color:'#4099c760'},
							{offset:0.9, color:'#439fce60'}
						]
					),
					stroke: 'none'
				},
				position: [0, 0],
				z: 16
			}));*/

			// 框框
			this.zr.add(this.spritesParam.screenStroke = new this.zrender.Rect
			({
				shape: {
					width: 1900 - 598,
					height: 990 - 10
					/*points: [
						[1900, 990], // 右下角 & 右下框右上角 D
						[598, 990],  // 左下角 C
						[598, 10],   // 左上角 A
						[1900, 10],  // 右上角 B
						[1900, 1072],// 右下框右下角 E3
						[1528, 1072],// 右下框左下角 E2
						[1503, 988]  // 右下框左上角 E1
					]*/
				},
				style: {
					fill: 'none',
					stroke: new this.zrender.LinearGradient(
						0, 1, 1, 0,
						[
							{offset:0.2, color:'#85d6ff'},
							{offset:0.9, color:'#290a59'}
						]
					),
					lineWidth: 6,
					shadowColor: 'black',
					shadowBlur: 5,
					shadowOffsetX: 3,
					shadowOffsetY: 3
				},
				position: [598, 10],
				z: 16
			}));
		},

		/*
			* 底部分
			*/
		createBottom () {
			// 白线
			this.zr.add(new this.zrender.Rect({
				shape: {
					width: this.width,
					height: 4
				},
				style: {
					stroke: 'none',
					fill: new this.zrender.LinearGradient(
						0, 0, 0, 1,
						[
							{offset:0, color:'#FFF'},
							{offset:1, color:'#FFF0'}
						]
					),
					opacity: 1
				},
				position: [0, 999],
				z: 201
			}));

			// 底
			this.zr.add(new this.zrender.Rect
			({
				shape: {
					width: this.width,
					height: 80
				},
				style: {
					fill: new this.zrender.LinearGradient(
						0, 0, 0, 1,
						[
							{offset:0.04, color:'#059279'},
							{offset:0.86, color:'#0d2a44'}
						]
					),
					opacity: 1
				},
				position: [0, 1000],
				z: 11
			}));

			// 右下角 z>=200
			this.zr.add(this.spritesParam.timerCorner = new this.zrender.Rect
			({
				shape: {
					width: 372,
					height: 80
				},
				style: {
					fill: new this.zrender.LinearGradient(
						0, 0, 10, 0,
						[
							{offset:0, color:'#FFF0'},
							{offset:0.2, color:'#FFF'},
							{offset:0.4, color:'#FFF0'},
							{offset:0.5, color:'#0000'},
							{offset:0.6, color:'#0005'},
						], true
					),
					opacity: 1
				},
				position: [this.width - 372, this.height - 80],
				z: 200
			}));
		},
		
		/* **********
			* 状态控制 *
			********** */

		onMessage (name, arg) {
			switch (name) {
				case 'chunk-width': {
					let width = arg.width;
					if (width < 0) {
						width = 0;
					} else if (width > 1000) {
						width = 1000;
					}

					this.spritesParam.timerCorner.attr({
						shape: {
							width: width
						},
						position: [this.width - width, this.height - 80]
					});
				} return;
			}
			console.log("bottom 收到命令: " + name);
			console.log(arg);
		},

	});
};

export default createScene;
